# ------------------------------------------------------------------------------
##### Set up                                                               -----
# ------------------------------------------------------------------------------

##### Libraries ----------------------------------------------------------------
library(tidyverse)
library(readxl)
library(marginaleffects)
library(readr)
library(stargazer)
library(ggtext)
library(broom)

##### Load data ----------------------------------------------------------------
difdef <- read_csv("data/difdef.csv") |> 
  mutate(inparty = case_when(inparty == "green" ~ "Green Party of\nEngland and Wales",
                             inparty == "snp" ~ "Scottish National Party",
                             inparty == "allianceparty" ~ "Alliance Party\nof Northern Ireland",
                             inparty == "socialdems" ~ "Social Democratic and\nLabour Party",
                             inparty == "libdem" ~ "Liberal Democrats",
                             inparty == "plaidcymru" ~ "Plaid Cymru",
                             inparty == "sinnfein" ~ "Sinn Feín",
                             inparty == "dup" ~ "Democratic Unionist Party",
                             inparty == "conservative" ~ "Conservative Party",
                             inparty == "uup" ~ "Ulster Unionist Party",
                             inparty == "reformuk" ~ "Reform UK",
                             inparty == "tuv" ~ "Traditional Unionist Voice",
                             inparty == "labour" ~ "Labour Party",
                             TRUE ~ inparty))

# ------------------------------------------------------------------------------
##### Descriptives used in main text                                       -----
# ------------------------------------------------------------------------------

##### Endnote 50 --------------------------------------------------------------
difference <- t.test(difdef$eval_pre, difdef$eval_post, paired = TRUE, conf.level = 0.95)

### Figure 2 -------------------------------------------------------------------
# Pre-treatment evaluations per party -----
inparty_pre <- difdef |> 
  mutate(inparty = case_when(inparty %in% c("Green Party of\nEngland and Wales",
                                            "Liberal Democrats",
                                            "Conservative Party",
                                            "Reform UK",
                                            "Labour Party") ~ inparty,
                             TRUE ~ "Other parties")) |> 
  group_by(inparty) |>
  summarise(mean = mean(eval_pre),
            count = n()) |> 
  mutate(mean = round(mean, 2),
         label = paste0(mean, "\n(n = ", count, ")"))
  
party_desc <- difdef |>
  mutate(inparty = case_when(inparty %in% c("Green Party of\nEngland and Wales",
                                            "Liberal Democrats",
                                            "Conservative Party",
                                            "Reform UK",
                                            "Labour Party") ~ inparty,
                             TRUE ~ "Other parties")) |>
  dplyr::select(inparty, eval_pre) |> 
  left_join(inparty_pre, by = "inparty")

ggplot(data = inparty_pre,
       aes(x = reorder(inparty, mean),
           y = eval_pre)) +
  
  # observations
  geom_point(data = party_desc,
             alpha = 0.3,
             size = 0.5,
             position = position_jitter(seed = 1, width = 0.1, height = 0.4),
             colour = "grey") +

  # distribution
  ggdist::stat_halfeye(data = party_desc,
                       adjust = 3,
                       width = 0.7,
                       justification = 0,
                       .width = 0,
                       point_colour = NA,
                       alpha = 0.3) +

  geom_boxplot(data = party_desc,
               width = .15,
               outlier.shape = NA,
               alpha = 0,
               linewidth = 0.5,
               coef = 0,
               colour = "grey") +
  
  # point estimates and n
  geom_text(aes(label = label,
                y = mean,
                x = reorder(inparty, mean)),
            size = 2.5,
            hjust = 0.5) +

  # formatting
  coord_cartesian(xlim = c(1.2, 5.9), clip = "off") +
  scale_y_continuous(limits = c(0, 10), breaks = seq(0, 10), expand = c(0, 0)) +
  theme_bw() +
  theme(panel.grid.minor = element_blank(),
        panel.grid.major.x = element_blank(),
        legend.position = "none",
        #axis.text.x = element_text(angle = 0, hjust = 1),
        axis.ticks.x = element_blank(),
        axis.title = element_blank())

ggsave(filename  = "figures/desc.png",
       width = 16,
       height = 14,
       dpi = 300,
       units = "cm")

above_midpoint <- difdef |> 
  mutate(midpoint = case_when(eval_pre == 5 ~ "mid",
                              eval_pre < 5 ~ "below",
                              eval_pre > 5 ~ "above")) |> 
  group_by(midpoint) |> 
  summarise(count = n())

eval_pre_desc <- difdef |> 
  group_by(eval_pre) |> 
  summarise(count = n()) |> 
  mutate(perc = paste0(round(count / nrow(difdef) * 100, 2), "%"))

# ------------------------------------------------------------------------------
##### Hypothesis 1                                                         -----
# ------------------------------------------------------------------------------

h1 <- lm(outcome ~ type + inparty + mayor + opposite,
         data = difdef)

h1_pred <- avg_predictions(h1, by = "type") |> 
  rename(actor = type) |> 
  mutate(model = "agg")

h1_actor <- lm(outcome ~ actor + inparty + mayor + opposite,
               data = difdef)

h1_actor_pred <- avg_predictions(h1_actor, by = "actor") |> 
  mutate(model = "dis")

##### Figure 3 -----------------------------------------------------------------
h1_plot <- bind_rows(h1_pred, h1_actor_pred) |> 
  mutate(stars = case_when(p.value < 0.05 & p.value >= 0.01 ~ "*",
                           p.value < 0.01 & p.value >= 0.001 ~ "**",
                           p.value < 0.001 ~ "***",
                           TRUE ~ ""),
         label = paste0(round(estimate, 2), stars, " [", round(conf.low, 2), "; ", round(conf.high, 2), "]")) |> 
  mutate(actor = case_when(actor == "institutional" ~ "**Institutional**",
                           actor == "political" ~ "**Political**",
                           actor == "social" ~ "**Social**",
                           actor == "judge" ~ "Judge",
                           actor == "civil servant" ~ "Civil servant",
                           actor == "military official" ~ "Military official",
                           actor == "out-party" ~ "Out-party politician",
                           actor == "in-party" ~ "In-party politician",
                           actor == "mayor" ~ "Mayor",
                           actor == "academic" ~ "Academic",
                           actor == "journalist" ~ "Journalist",
                           actor == "NGO" ~ "International human  \nrights watchdog",
                           TRUE ~ actor))

# set order
h1_plot$actor <- factor(h1_plot$actor, levels = c("International human  \nrights watchdog", "Journalist", "Academic", "**Social**",
                                                  "Mayor", "In-party politician", "Out-party politician", "**Political**",
                                                  "Military official", "Civil servant", "Judge", "**Institutional**"))

# plot parameters
h1_colours <- c("agg" = "#C33C54",
                "dis" = "#37718E")

h1_fill <- c("agg" = "#C33C54",
             "dis" = "white")

ggplot(data = h1_plot,
       aes(x = estimate,
           y = actor)) +
  geom_vline(xintercept = 0,
             colour = "darkgrey",
             linewidth = 0.2) +
  geom_errorbarh(aes(xmin = conf.low,
                     xmax = conf.high,
                     colour = model),
                 height = 0) +
  geom_point(aes(colour = model,
                 fill= model),
             size = 3,
             shape = 21) +
  geom_text(aes(label = label),
            nudge_y = 0.3,
            size = 2.5) +
  scale_colour_manual(values = h1_colours) +
  scale_fill_manual(values = h1_fill) +
  theme_bw() +
  theme(axis.title = element_blank(),
        legend.position = "none",
        axis.ticks.y = element_blank(),
        axis.text.y = element_markdown())

ggsave(filename  = "figures/h1.png",
       width = 16,
       height = 12,
       dpi = 300,
       units = "cm")

# Tables 
stargazer(h1, h1_actor,
          title = "Effect of democratic defenders on democracy evaluation",
          column.labels = c("Aggregate type of actor", "Specific actor"),
          dep.var.caption = "",
          dep.var.labels.include = FALSE,
          align = TRUE,
          omit.stat = c("LL", "ser", "f"),
          no.space = TRUE,
          #single.row = TRUE,
          star.cutoffs = c(0.05, 0.01, 0.001),
          type = "latex",
          out = "tables/h1.tex",
          label = "tab:h1")

h1_type_mm <- h1_pred |> 
  dplyr::select(actor, estimate, conf.low, conf.high) |> 
  mutate(label = paste0(round(estimate, 2), " [", round(conf.low, 2), "; ", round(conf.high, 2), "]")) |> 
  dplyr::select(actor, label) |> 
  rename(Type = actor,
         "Marginal Mean (with 95% CIs)" = label)

stargazer(h1_type_mm, 
          title = "Effect of type of democratic defenders on democracy evaluation (marginal means)",
          summary = FALSE,
          no.space = TRUE,
          single.row = TRUE,
          star.cutoffs = c(0.05, 0.01, 0.001),
          type = "latex",
          out = "tables/h1_type_mm.tex",
          label = "tab:h1_type_mm")

h1_actor_mm <- h1_actor_pred |> 
  dplyr::select(actor, estimate, conf.low, conf.high) |> 
  mutate(label = paste0(round(estimate, 2), " [", round(conf.low, 2), "; ", round(conf.high, 2), "]")) |> 
  dplyr::select(actor, label) |> 
  rename(Actor = actor,
         "Marginal Mean (with 95% CIs)" = label)

stargazer(h1_actor_mm, 
          title = "Effect of specific actors on democracy evaluation (marginal means)",
          summary = FALSE,
          no.space = TRUE,
          single.row = TRUE,
          star.cutoffs = c(0.05, 0.01, 0.001),
          type = "latex",
          out = "tables/h1_actor_mm.tex",
          label = "tab:h1_actor_mm")

# ------------------------------------------------------------------------------
##### Hypotheses 2 and 3                                                         -----
# ------------------------------------------------------------------------------
# Deviation from preregistration
# See Online Appendix

##### Actor as predictor of biases ---------------------------------------------

### Actors -----
# embedded knowledge
m_recog <- lm(perception_recog ~ actor + inparty + mayor + opposite,
              data = difdef)

recog_pred <- avg_predictions(m_recog, by = "actor") |> 
  mutate(perception = "recognition",
         dimension = "Perceptions of  \n**embedded knowledge**",
         iv = "actor")

m_comt <- lm(perception_comt ~ actor + inparty + mayor + opposite,
             data = difdef)

comt_pred <- avg_predictions(m_comt, by = "actor") |> 
  mutate(perception = "commitment",
         dimension = "Perceptions of  \n**embedded knowledge**",
         iv = "actor")

# political neutrality
m_neut <- lm(perception_neut ~ actor + inparty + mayor + opposite,
             data = difdef)

neut_pred <- avg_predictions(m_neut, by = "actor") |> 
  mutate(perception = "neutral",
         dimension = "Perceptions of  \n**political impartiality**",
         iv = "actor")

m_leri <- lm(leri_bias ~ actor + inparty + mayor + opposite,
             data = difdef)

leri_pred <- avg_predictions(m_leri, by = "actor") |> 
  mutate(perception = "left-right",
         dimension = "Perceptions of  \n**political impartiality**",
         iv = "actor")

### Categories -----
# embedded knowledge
m_recog_type <- lm(perception_recog ~ type + inparty + mayor + opposite,
                   data = difdef)

recog_type_pred <- avg_predictions(m_recog_type, by = "type") |> 
  mutate(perception = "recognition",
         dimension = "Perceptions of  \n**embedded knowledge**",
         iv = "type")

m_comt_type <- lm(perception_comt ~ type + inparty + mayor + opposite,
                  data = difdef)

comt_type_pred <- avg_predictions(m_comt_type, by = "type") |> 
  mutate(perception = "commitment",
         dimension = "Perceptions of  \n**embedded knowledge**",
         iv = "type")

# political neutrality
m_neut_type <- lm(perception_neut ~ type + inparty + mayor + opposite,
                  data = difdef)

neut_type_pred <- avg_predictions(m_neut_type, by = "type") |> 
  mutate(perception = "neutral",
         dimension = "Perceptions of  \n**political impartiality**",
         iv = "type")

m_leri_type <- lm(leri_bias ~ type + inparty + mayor + opposite,
                  data = difdef)

leri_type_pred <- avg_predictions(m_leri_type, by = "type") |> 
  mutate(perception = "left-right",
         dimension = "Perceptions of  \n**political impartiality**",
         iv = "type")

### Merge
perceptions <- bind_rows(recog_pred, neut_pred, comt_pred, leri_pred,
                         recog_type_pred, neut_type_pred, comt_type_pred, leri_type_pred) |> 
  mutate(type = case_when(type == "institutional" ~ "Institutional",
                          type == "social" ~ "Social",
                          type == "political" ~ "Political"),
         actor = ifelse(is.na(actor), type, actor),
         actor = case_when(actor == "institutional" ~ "Institutional",
                           actor == "political" ~ "Political",
                           actor == "social" ~ "Social",
                           actor == "judge" ~ "Judge",
                           actor == "civil servant" ~ "Civil servant",
                           actor == "military official" ~ "Military official",
                           actor == "out-party" ~ "Out-party politician",
                           actor == "in-party" ~ "In-party politician",
                           actor == "mayor" ~ "Mayor",
                           actor == "academic" ~ "Academic",
                           actor == "journalist" ~ "Journalist",
                           actor == "NGO" ~ "International human  \nrights watchdog",
                           TRUE ~ actor),
         label = paste0(round(estimate, 2), " [", round(conf.low, 2), "; ", round(conf.high, 2), "]"))

##### Figure 4 -----------------------------------------------------------------
### plot parameters
# set order
perceptions$actor <- factor(perceptions$actor, levels = c("International human  \nrights watchdog", "Journalist", "Academic",
                                                          "Mayor", "In-party politician", "Out-party politician",
                                                          "Military official", "Civil servant", "Judge",
                                                          "Social", "Political", "Institutional"))

perceptions$perception <- factor(perceptions$perception, levels = c("left-right", "neutral", "recognition", "commitment"))

perceptions$iv <- factor(perceptions$iv, levels = c("type", "actor"))

perceptions$dimension <- factor(perceptions$dimension, levels = c("Perceptions of  \n**political impartiality**", "Perceptions of  \n**embedded knowledge**"))

# colours
perception_colours <- c("neutral" = "#C33C54",
                        "left-right" = "#37123C",
                        "recognition" = "#37718E",
                        "commitment" = "#091540")

perception_labels <- c("neutral" = "**Neutrality**  \n(Lower is more neutral)",
                       "left-right" = "**Left-right bias**  \n(Lower is less biased)",
                       "recognition" = "**Ability to recognize autocratization**  \n(Higher is more ability)",
                       "commitment" = "**Commitment to democracy**  \n(Higher is more commitment)") 

perception_shapes <- c("neutral" = 22,
                       "left-right" = 23,
                       "recognition" = 21,
                       "commitment" = 24)

# plot
ggplot(data = perceptions,
       aes(x = estimate,
           y = actor)) +
  
  geom_errorbarh(aes(xmin = conf.low, 
                     xmax = conf.high,
                     colour = perception),
                 height = 0,
                 position = position_dodge(width = 0.5),
                 linewidth = 0.2) +
  
  geom_point(aes(fill = perception,
                 shape = perception,
                 colour = perception),
             position = position_dodge(width = 0.5),
             size = 1) +
  
  # geom_text(aes(label = label,
  #               colour = perception),
  #           size = 2.5,
  #           position = position_dodge(width = 1.1)) +
  
  facet_grid(iv ~ dimension,
             scales = "free_y",
             space = "free",
             labeller = labeller(iv = c("actor" = "Specific actor", "type" = "Category"))) +
  
  # formatting
  theme_bw() +
  theme(legend.position = "bottom",
        legend.title = element_blank(),
        legend.text = element_markdown(),
        legend.text.position = "bottom",
        legend.key.spacing.x = unit(1.5, "cm"),
        legend.location = "plot",
        panel.grid.major.x = element_line(),
        axis.text.y = element_markdown(),
        axis.title = element_blank(),
        strip.text = element_markdown(),
        axis.ticks.y = element_blank()) +
  scale_x_continuous(limits = c(1, 8), breaks = 1:8) +
  scale_fill_manual(values = perception_colours, labels = perception_labels) +
  scale_colour_manual(values = perception_colours, labels = perception_labels) +
  scale_shape_manual(values = perception_shapes, labels = perception_labels)

# save
ggsave(filename  = "figures/perceptions_know.png",
       width = 20,
       height = 12,
       dpi = 300,
       units = "cm")

# Tables
stargazer(m_neut, m_leri, m_recog, m_comt,
          title = "Elite democratic defender as predictor of citizen perceptions",
          column.labels = c("Partisanship", "Left-right bias", "Ability to recognize", "Commitment to democracy"),
          dep.var.caption = "",
          dep.var.labels.include = FALSE,
          align = TRUE,
          omit.stat = c("LL", "ser", "f"),
          no.space = TRUE,
          #single.row = TRUE,
          star.cutoffs = c(0.05, 0.01, 0.001),
          keep = c("type.*", "actor.*"),
          notes = "Some variables omitted from table for clarity",
          type = "latex",
          out = "tables/actor_bias.tex",
          label = "tab:actor_bias")

stargazer(m_neut_type, m_leri_type, m_recog_type, m_comt_type,
          title = "Elite democratic defender as predictor of citizen perceptions",
          column.labels = c("Partisanship", "Left-right bias", "Ability to recognize", "Commitment to democracy"),
          dep.var.caption = "",
          dep.var.labels.include = FALSE,
          align = TRUE,
          omit.stat = c("LL", "ser", "f"),
          no.space = TRUE,
          #single.row = TRUE,
          star.cutoffs = c(0.05, 0.01, 0.001),
          keep = c("type.*", "actor.*"),
          notes = "Some variables omitted from table for clarity",
          type = "latex",
          out = "tables/type_bias.tex",
          label = "tab:type_bias")

perceptions_table <- perceptions |> 
  dplyr::select(actor, estimate, conf.low, conf.high, perception) |> 
  mutate(label = paste0(round(estimate, 2), " [", round(conf.low, 2), "; ", round(conf.high, 2), "]")) |> 
  dplyr::select(actor, label, perception) |> 
  pivot_wider(names_from = perception,
              values_from = label) |> 
  mutate(actor = as.character(actor))

perceptions_table[] <- lapply(perceptions_table, \(x) gsub("[\r\n]", " ", x))

stargazer(perceptions_table,
          title = "Elite democratic defender as predictor of citizen perceptions (marginal means)",
          summary = FALSE,
          no.space = TRUE,
          #single.row = TRUE,
          star.cutoffs = c(0.05, 0.01, 0.001),
          type = "latex",
          out = "tables/actor_bias_mm.tex",
          label = "tab:actor_bias_mm")

# ------------------------------------------------------------------------------
##### Exploration                                                          -----
# ------------------------------------------------------------------------------
recog_expl <- lm(eval_post ~ perception_recog + 
                   inparty + pol_interest + dem_sup + leri + pol_trust_mean +
                   Sex + Age + ethnicity,
                 data = difdef)

recog_effect <- tidy(recog_expl) |> 
  dplyr::select(term, estimate, std.error, p.value) |> 
  filter(term == "perception_recog")

summary(recog_expl) # for exact p-values in the text

comt_expl <- lm(eval_post ~ perception_comt + 
                  inparty + pol_interest + dem_sup + leri + pol_trust_mean +
                  Sex + Age + ethnicity,
                data = difdef)

comt_effect <- tidy(comt_expl) |> 
  dplyr::select(term, estimate, std.error, p.value) |> 
  filter(term == "perception_comt")

summary(comt_expl) # for exact p-values in the text

neut_expl <- lm(eval_post ~ perception_neut + 
                  inparty + pol_interest + dem_sup + leri + pol_trust_mean +
                  Sex + Age + ethnicity,
                data = difdef)

neut_effect <- tidy(neut_expl) |> 
  dplyr::select(term, estimate, std.error, p.value) |> 
  filter(term == "perception_neut")

summary(neut_expl) # for exact p-values in the text

leri_expl <- lm(eval_post ~ leri_bias + 
                  inparty + pol_interest + dem_sup + leri + pol_trust_mean +
                  Sex + Age + ethnicity,
                data = difdef)

leri_effect <- tidy(leri_expl) |> 
  dplyr::select(term, estimate, std.error, p.value) |> 
  filter(term == "leri_bias")

summary(leri_expl) # for exact p-values in the text

# merge
perc_expl <- bind_rows(recog_effect, comt_effect, neut_effect, leri_effect) |> 
  mutate(label = paste0(round(estimate, 2), " (", round(std.error, 2), ")"),
         name = case_when(term == "perception_comt" ~ "Perceived **commitment**  \nto democracy",
                          term == "perception_recog" ~ "Perceived **ability** to  \nrecognize autocratization",
                          term == "perception_neut" ~ "Perceived **partiality**",
                          term == "leri_bias" ~ "Perceived **left-right bias**")) 

##### Figure 5 -----------------------------------------------------------------
### plot parameters
# set order
perc_expl$term <- factor(perc_expl$term, levels = c("perception_comt", "perception_recog", 
                                                    "perception_neut", "leri_bias"))

perc_expl_colours <- c("perception_neut" = "#C33C54",
                       "leri_bias" = "#37123C",
                       "perception_recog" = "#37718E",
                       "perception_comt" = "#091540")

perc_expl_shapes <- c("perception_neut" = 22,
                      "leri_bias" = 23,
                      "perception_recog" = 21,
                      "perception_comt" = 24)

# plot
ggplot(data = perc_expl,
       aes(x = estimate,
           y = name)) +
  
  geom_vline(xintercept = 0,
             colour = "darkgrey",
             linewidth = 0.2) +
  
  geom_point(aes(colour = term,
                 fill = term,
                 shape = term),
             size = 1) +
  
  geom_errorbarh(aes(xmin = estimate - 1.96 * std.error,
                     xmax = estimate + 1.96 * std.error,
                     colour = term),
                 height = 0,
                 linewidth = 0.2) +
  
  geom_text(aes(label = label,
                colour = term),
            size = 2.5,
            hjust = 0.5,
            nudge_y = 0.15) +
  
  # formatting
  theme_bw() +
  theme(legend.position = "none",
        legend.title = element_blank(),
        legend.text = element_markdown(),
        legend.text.position = "bottom",
        legend.key.spacing.x = unit(1.5, "cm"),
        legend.location = "plot",
        panel.grid.major.x = element_line(),
        axis.text.y = element_markdown(),
        axis.title = element_blank(),
        axis.ticks.y = element_blank()) +
  #scale_x_continuous(limits = c(1, 8), breaks = 1:8) +
  scale_fill_manual(values = perc_expl_colours) +
  scale_colour_manual(values = perc_expl_colours) +
  scale_shape_manual(values = perc_expl_shapes)
  
# save
ggsave(filename  = "figures/explore.png",
       width = 16,
       height = 8,
       dpi = 300,
       units = "cm")

# Tables 
stargazer(recog_expl, comt_expl,
          title = "Effect of respondent perceptions of elite embedded knowledge on respondent democracy evaluation of the autocratic proposal",
          column.labels = c("Perceived ability to recognize autocratization", "Perceived commitment to democracy"),
          dep.var.caption = "DV = post-treatment democracy evaluation",
          dep.var.labels.include = FALSE,
          align = TRUE,
          omit.stat = c("LL", "ser", "f"),
          no.space = TRUE,
          #single.row = TRUE,
          star.cutoffs = c(0.05, 0.01, 0.001),
          type = "latex",
          out = "tables/explore_know.tex",
          label = "tab:explore_know")

stargazer(neut_expl, leri_expl,
          title = "Effect of respondent perceptions of elite impartiality on respondent democracy evaluation of the autocratic proposal",
          column.labels = c("Perceived neutrality", "Perceived left-right bias"),
          dep.var.caption = "DV = post-treatment democracy evaluation",
          dep.var.labels.include = FALSE,
          align = TRUE,
          omit.stat = c("LL", "ser", "f"),
          no.space = TRUE,
          #single.row = TRUE,
          star.cutoffs = c(0.05, 0.01, 0.001),
          type = "latex",
          out = "tables/explore_neut.tex",
          label = "tab:explore_neut")

# /./ End of code /./ #
